package main

import (
	"io"
	"net/http"
	"net/rpc"
	"net/rpc/jsonrpc"

	"gitlab.com/go-course-project/go17/skills/rpc/hello_world/service"
)

var _ service.HelloService = (*HelloServiceServer)(nil)

// 实现业务功能
// req := &HelloRequest{}
// resp := &HelloResponse{}
// err := &HelloServiceServer{}.Hello(req, resp)
// net/rpc
// 1. 写好的对象， 注册给RPC Server
// 2. 再把RPC Server 启动起来
type HelloServiceServer struct {
}

// HTTP Handler
func (h *HelloServiceServer) Hello(request *service.HelloRequest, response *service.HelloResponse) error {
	response.Message = "hello:" + request.MyName
	return nil
}

func NewRPCReadWriteCloserFromHTTP(w http.ResponseWriter, r *http.Request) *RPCReadWriteCloser {
	return &RPCReadWriteCloser{w, r.Body}
}

type RPCReadWriteCloser struct {
	io.Writer
	io.ReadCloser
}

func main() {
	// 1. 把业务 注册给RPC
	// 2. RPC 业务RPC必须是满足条件的接口:  (req any, req any) error
	// Hello(request *HelloRequest, response *HelloResponse) error
	if err := rpc.RegisterName("HelloService", &HelloServiceServer{}); err != nil {
		panic(err)
	}

	// RPC的服务架设在“/jsonrpc”路径，
	// 在处理函数中基于http.ResponseWriter和http.Request类型的参数构造一个io.ReadWriteCloser类型的conn通道。
	// 然后基于conn构建针对服务端的json编码解码器。
	// 最后通过rpc.ServeRequest函数为每次请求处理一次RPC方法调用
	http.HandleFunc("/jsonrpc", func(w http.ResponseWriter, r *http.Request) {
		conn := NewRPCReadWriteCloserFromHTTP(w, r)
		rpc.ServeRequest(jsonrpc.NewServerCodec(conn))
	})

	// protobuf.HelloRequest.MyName
	http.ListenAndServe(":1234", nil)
}
